home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Bitmap Libraries 2.0 / Examples / Rotation / Rotation.c < prev    next >
Text File  |  1996-03-05  |  10KB  |  404 lines

  1.  
  2. /* File Rotation.c Copyright (C) 1996 by John R. Montbriand.  All Rights Reserved. */
  3.  
  4. /* File Rotation.c
  5.  
  6.     Copyright (C) 1996 by John Montbriand.  All Rights Reserved.
  7.     
  8.     Distribute freely in areas where the laws of copyright apply.
  9.     
  10.     Use at your own risk.
  11.     
  12.     Do not distribute modified copies.
  13.     
  14.     These various BitMap libraries and examples are for free!
  15.     
  16.     See the accompanying file BitMap.txt for details.
  17.     
  18. */
  19.  
  20. /* written in Geneva 9, tabs at 4 */
  21.  
  22. /* •••••••••••••••••••••• INCLUDES •••••••••••••••••••••• */
  23.  
  24. #include <Types.h>
  25. #include <QuickDraw.h>
  26. #include <Fonts.h>
  27. #include <Windows.h>
  28. #include <Menus.h>
  29. #include <TextEdit.h>
  30. #include <Dialogs.h>
  31. #include <AppleEvents.h>
  32. #include <TextUtils.h>
  33. #include <OSUtils.h>
  34. #include <ToolUtils.h>
  35. #include <Desk.h>
  36. #include <Memory.h>
  37. #include <Errors.h>
  38. #include <Gestalt.h>
  39. #include <Traps.h>
  40. #include <SegLoad.h>
  41.  
  42. #include "BitMap.h"
  43.  
  44. /* •••••••••••••••••••••• CONSTANTS •••••••••••••••••••••• */
  45.  
  46. #define kAboutBoxID 128
  47. #define kErrorBoxID 129
  48. #define kMainWindID 128
  49. #define kMenuBarID 128
  50.  
  51. #define mApple 128
  52. #define iAbout 1
  53. #define iAccessoryOne 3
  54.  
  55. #define mFile 129
  56. #define iQuit 1
  57.  
  58. #define mEdit 130
  59. #define iUndo 1
  60. #define iCut 3
  61. #define iCopy 4
  62. #define iPaste 5
  63. #define iClear 6
  64.  
  65. /* •••••••••••••••••••••• GLOBALS •••••••••••••••••••••• */
  66.  
  67. Boolean PROGRAM_RUNNING = true;
  68. Boolean PROGRAM_FRONT = true;
  69. Boolean HAS_APPLEEVENTS = false;
  70. Boolean HAS_WAITNEXTEVENT = false;
  71.  
  72. QDGlobals    qd;
  73.  
  74. DialogPtr gABOUTBOX = NULL;
  75. WindowPtr gMAIN_WINDOW = NULL;
  76.  
  77.  
  78. /* •••••••••••••••••••••• ERROR HANDLER •••••••••••••••••••••• */
  79.  
  80. /* Terminate, displays an error box containing the error number and then terminates
  81.     the application. */
  82. void Terminate(OSErr err) {
  83.     Str255 s;
  84.     NumToString(err, s);
  85.     ParamText(s, NULL, NULL, NULL);
  86.     Alert(kErrorBoxID, NULL);
  87.     ExitToShell();
  88. }
  89.  
  90. /* •••••••••••••••••••••• THE EXAMPLE PART •••••••••••••••••••••• */
  91. /* NOTE:  all of the example code to do with bitmaps is included in this part of the
  92. program.  The rest of the program has to do with the usual things that go into
  93. applications.  */
  94.  
  95.  
  96. /*DrawWindowContents is called in response to every update event for the main
  97.     window.  this is the part where we do drawing in the bitmaps */
  98. void DrawWindowContents(WindowPtr wp) {
  99.     PicHandle pic;
  100.     BitMap *bits, *rbits, *sbits;
  101.     short the_top;
  102.     BitMapPort* bmp;
  103.     
  104.     EraseRect(&wp->portRect);
  105.  
  106.         /* logo picture */
  107.     bits = PICTToBitMap(GetPicture(128));
  108.     if (bits != NULL) {
  109.         rbits = RotateBitMap(bits, bits->bounds.right/2, bits->bounds.bottom/2, 23.0);
  110.         if (rbits != NULL) {
  111.             PlotBitMap(rbits, 0, 0, srcOr);
  112.             KillBitMap(rbits);
  113.         }
  114.         the_top = bits->bounds.bottom;
  115.         KillBitMap(bits);
  116.     }
  117.     
  118.         /* hello world string */
  119.     bits = StringToBitMap(0, 12, 0, "\pHello World");
  120.     
  121.     if (bits != NULL) {
  122.         PlotBitMap(bits, (200-bits->bounds.right)/2, the_top, srcOr);
  123.         
  124.         rbits = FlipVertical(bits);
  125.         if (rbits != NULL) {
  126.             PlotBitMap(rbits, (200-bits->bounds.right)/2, the_top + bits->bounds.bottom, srcOr);
  127.             KillBitMap(rbits);
  128.         }
  129.         
  130.         rbits = FlipHorizontal(bits);
  131.         if (rbits != NULL) {
  132.             PlotBitMap(rbits, (200-bits->bounds.right)/2, the_top + bits->bounds.bottom*2, srcOr);
  133.             KillBitMap(rbits);
  134.         }
  135.         
  136.         rbits = RotateLeft(bits);
  137.         if (rbits != NULL) {
  138.             PlotBitMap(rbits, 20, the_top + 20, srcOr);
  139.             KillBitMap(rbits);
  140.         }
  141.         
  142.         rbits = RotateRight(bits);
  143.         if (rbits != NULL) {
  144.             PlotBitMap(rbits, 200-20-rbits->bounds.right, the_top + 20, srcOr);
  145.             KillBitMap(rbits);
  146.         }
  147.         
  148.         rbits = NewBitMap(bits->bounds.right, bits->bounds.right);
  149.         if (rbits != NULL) {
  150.             WithBitMap(rbits, bmp) {
  151.                 PlotBitMap(bits, 0, (rbits->bounds.bottom - bits->bounds.bottom)/2, srcOr);
  152.             }
  153.             
  154.             sbits = RotateBitMap(rbits, rbits->bounds.right/2, rbits->bounds.bottom/2, -37.0);
  155.             if (sbits != NULL) {
  156.                 PlotBitMap(sbits, (200-bits->bounds.right)/2, the_top + bits->bounds.bottom*3, srcOr);
  157.                 KillBitMap(sbits);
  158.             }
  159.         
  160.             KillBitMap(rbits);
  161.         }
  162.         
  163.         KillBitMap(bits);
  164.     }
  165.  
  166. }
  167.  
  168. /*ClickWindowContents is called every time a mouse down event occurs in the
  169.     main program window allowing for some interaction. */
  170. void ClickWindowContents(WindowPtr wp, Point where) {
  171.  
  172.  
  173. }
  174.  
  175. /* InitExample is called at program startup after the main window has been
  176.     created to allow the example to set itself up.  I put it here so all the example
  177.     code would be together in one section. */
  178. OSErr InitExample(WindowPtr wp) {
  179.     return noErr;
  180. }
  181.  
  182.  
  183. /* •••••••••••••••••••••• MENU COMMANDS •••••••••••••••••••••• */
  184.  
  185. /* HandleMenuCommand is called after MenuKey or MenuSelect to handle the processing
  186.      of menu commands.  Here there aren't too many, just the standard ones */
  187. void HandleMenuCommand(short menu, short item) {
  188.     if (menu == mApple) {
  189.         if (item == iAbout) {
  190.             if (gABOUTBOX != NULL)
  191.                 SelectWindow(gABOUTBOX);
  192.             else gABOUTBOX = GetNewDialog(kAboutBoxID, NULL, (WindowPtr) (-1));
  193.         } else if (item >= iAccessoryOne) {
  194.             Str255 itemString;
  195.             GetItem(GetMHandle(menu), item, itemString);
  196.             OpenDeskAcc(itemString);
  197.         }
  198.     } else if (menu == mFile) {
  199.         switch (item) {
  200.             case iQuit:
  201.                 PROGRAM_RUNNING = false;
  202.                 break;
  203.         }
  204.     } else if (menu == mEdit) {
  205.         SystemEdit(item-1);
  206.     }
  207.     HiliteMenu(0);
  208. }
  209.  
  210. /* MenuPreflightCheck is called immediately before MenuKey or MenuSelect.  In your
  211.     application you would use this routine to appropriately enable or disable different
  212.     commands depending on what can be done at the time of the mouse click or key
  213.     command. */
  214. void MenuPreflightCheck(void) {
  215.     /* none here*/
  216. }
  217.  
  218.  
  219. /* •••••••••••••••••••••• EVENT HANDLING •••••••••••••••••••••• */
  220.  
  221. /* HandleMouseDownEvent is called to process mouse down events */
  222. void HandleMouseDownEvent(EventRecord *ev) {
  223.     WindowPtr target;
  224.     switch ( FindWindow(ev->where, &target) ) {
  225.         case inDesk:
  226.             break;
  227.         case inSysWindow:
  228.             SystemClick(ev, target);
  229.             break;
  230.         case inContent:
  231.             if (target != FrontWindow())
  232.                 SelectWindow(target);
  233.             else if (target == gMAIN_WINDOW) {
  234.                 Point where;
  235.                 where = ev->where;
  236.                 SetPort(target);
  237.                 GlobalToLocal(&where);
  238.                 ClickWindowContents(target, where);
  239.             }
  240.             break;
  241.         case inDrag:
  242.             {    Rect r = qd.screenBits.bounds;
  243.                 if (target != FrontWindow()) SelectWindow(target);
  244.                 SetPort(target);
  245.                 InsetRect(&r, 4, 4);
  246.                 r.top += 20;
  247.                 DragWindow(target, ev->where, &r);
  248.             }
  249.             break;
  250.         case inGoAway:
  251.             if (TrackGoAway(target, ev->where)) {
  252.                 if (target == gABOUTBOX) {
  253.                     DisposeDialog(gABOUTBOX);
  254.                     gABOUTBOX = NULL;
  255.                 } else PROGRAM_RUNNING = false;
  256.             }
  257.             break;
  258.         case inMenuBar:
  259.             {    long mnRes;
  260.                 MenuPreflightCheck();
  261.                 if (HiWord(mnRes = MenuSelect(ev->where)) != 0)
  262.                     HandleMenuCommand(HiWord(mnRes), LoWord(mnRes));
  263.             }
  264.             break;
  265.     }
  266. }
  267.  
  268. /* SystemSwapTask can be called from anywhere in your application.  basically it collects
  269.     events and gives the system time to do its thing. */
  270. void SystemSwapTask(void) {
  271.     EventRecord ev;
  272.     
  273.         /* get the next event */
  274.     if (HAS_WAITNEXTEVENT) {
  275.         if (!WaitNextEvent(everyEvent, &ev, 0, NULL)) ev.what = nullEvent;
  276.     } else {
  277.         if (!GetNextEvent(everyEvent, &ev)) ev.what = nullEvent;
  278.         SystemTask();
  279.     }
  280.     
  281.     if ((ev.what == keyDown || ev.what == autoKey) && (ev.modifiers & cmdKey) != 0) {
  282.         long mnRes;
  283.         MenuPreflightCheck();
  284.         if (HiWord(mnRes = MenuKey((char) (ev.message & charCodeMask))) != 0)
  285.             HandleMenuCommand(HiWord(mnRes), LoWord(mnRes));
  286.     } else if (IsDialogEvent(&ev)) {
  287.         DialogPtr theDialog;
  288.         short itemHit;
  289.         DialogSelect(&ev, &theDialog, &itemHit);
  290.     } else if (ev.what == mouseDown) {
  291.         HandleMouseDownEvent(&ev);
  292.     } else if (ev.what == updateEvt) {
  293.         WindowPtr wp;
  294.         wp = (WindowPtr) ev.message;
  295.         SetPort(wp);
  296.         BeginUpdate(wp);
  297.         DrawWindowContents(wp);
  298.         EndUpdate(wp);
  299.     } else if (ev.what == kHighLevelEvent) {
  300.         if (HAS_APPLEEVENTS)
  301.             AEProcessAppleEvent(&ev);
  302.     } else if (ev.what == osEvt) {
  303.         if (((ev.message >> 24) & 0x0FF) == suspendResumeMessage)
  304.             PROGRAM_FRONT = (ev.message & resumeFlag) != 0;
  305.     }
  306.     
  307. }
  308.  
  309.  
  310. /* •••••••••••••••••••••• APPLE EVENTS •••••••••••••••••••••• */
  311.  
  312. /* QuitEventHandler called for quit apple events.  all we do here is set the running
  313.     flag to false */
  314. pascal OSErr QuitEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
  315.     DescType retType;
  316.     Size actSize;
  317.     OSErr err;
  318.     err = AEGetAttributePtr(appleEvt, keyMissedKeywordAttr, typeWildCard, &retType, NULL, 0, &actSize);
  319.     if (err == errAEDescNotFound) {
  320.         PROGRAM_RUNNING = false;
  321.         return noErr;
  322.     } else if (err == noErr)
  323.         return errAEEventNotHandled;
  324.     else return err;
  325. }
  326.  
  327.  
  328. /* •••••••••••••••••••••• TEST FOR TRAPS •••••••••••••••••••••• */
  329.  
  330. unsigned short NumToolboxTraps(void) {
  331.     if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  332.         return 0x0200;
  333.     else return 0x0400;
  334. }
  335.  
  336. TrapType FindTrapType(unsigned short theTrap) {
  337.     if (theTrap & 0x0800)
  338.         return ToolTrap;
  339.     else return OSTrap;
  340. }
  341.  
  342. Boolean TrapAvailable(unsigned short theTrap) {
  343.     unsigned short localTrap = theTrap;
  344.     TrapType tType = FindTrapType(localTrap);
  345.     if ( tType == ToolTrap ) {
  346.         localTrap &= 0x07FF;
  347.         if ( localTrap >= NumToolboxTraps() )
  348.             localTrap = _Unimplemented;
  349.     }
  350.     return NGetTrapAddress(localTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap);
  351. }
  352.  
  353.  
  354. /* •••••••••••••••••••••• MAIN PROGRAM •••••••••••••••••••••• */
  355.  
  356. void main(void) {
  357.     OSErr err;
  358.     long response;
  359.  
  360.         /* determine features of the machine */
  361.     if (Gestalt(gestaltAppleEventsAttr, &response) != noErr) response = 0;
  362.     HAS_APPLEEVENTS = ((response & (1<<gestaltAppleEventsPresent)) != 0);
  363.     HAS_WAITNEXTEVENT = TrapAvailable(_WaitNextEvent);
  364.     
  365.         /* initialize the toolbox, etc.. */
  366.     SetApplLimit( GetApplLimit() - (8*1024) );
  367.     MaxApplZone();
  368.     InitGraf(&qd.thePort);
  369.     InitFonts();
  370.     InitWindows();
  371.     TEInit();
  372.     InitMenus();
  373.     InitDialogs(NULL);
  374.     InitCursor();
  375.     if (HAS_APPLEEVENTS) {
  376.         err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  377.                     NewAEEventHandlerProc(QuitEventHandler), 0, false);
  378.         if (err != noErr) goto bail;
  379.     }
  380.     SetMenuBar(GetNewMBar(kMenuBarID));
  381.     AddResMenu(GetMHandle(mApple), 'DRVR');
  382.     DrawMenuBar();
  383.     gMAIN_WINDOW = GetNewWindow(kMainWindID, NULL, (WindowPtr) (-1));
  384.     SetPort(gMAIN_WINDOW);
  385.     err = InitExample(gMAIN_WINDOW);
  386.  
  387.         /* set up some globals */
  388.     PROGRAM_RUNNING = true;
  389.     PROGRAM_FRONT = true;
  390.     
  391.         /* loop until PROGRAM_RUNNING is false */
  392.     while (PROGRAM_RUNNING)
  393.         SystemSwapTask();
  394.     
  395.     return;
  396.     
  397. bail:
  398.     Terminate(err);
  399. }
  400.  
  401.  
  402. /* end File BitMap.c */
  403.  
  404.